package fi.otavanopisto.pyramus.webhooks;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.Stateful;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@Stateful
@Dependent
public class WebhookController {
@Inject
private Logger logger;
@PostConstruct
public void init() {
executorService = Executors.newSingleThreadExecutor();
}
public void sendWebhookNotifications(List<Webhook> webhooks, WebhookPayload<?> payload) {
if (!webhooks.isEmpty()) {
ObjectMapper objectMapper = new ObjectMapper();
try {
String data = objectMapper.writeValueAsString(payload);
for (Webhook webhook : webhooks) {
FutureTask<Boolean> futureTask = new FutureTask<>(new NotificationCallable(webhook.getUrl(), webhook.getSignature(), data));
executorService.execute(futureTask);
}
} catch (JsonProcessingException e) {
logger.log(Level.SEVERE, "Failed to send webhook notifications", e);
}
}
}
private ExecutorService executorService;
private class NotificationCallable implements Callable<Boolean> {
public NotificationCallable(String url, String signature, String data) {
this.url = url;
this.signature = signature;
this.data = data;
}
@Override
public Boolean call() throws Exception {
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
HttpPost httpPost = new HttpPost(url);
try {
StringEntity dataEntity = new StringEntity(data);
try {
httpPost.addHeader("X-Pyramus-Signature", signature);
httpPost.setEntity(dataEntity);
client.execute(httpPost);
return true;
} finally {
EntityUtils.consume(dataEntity);
}
} finally {
httpPost.releaseConnection();
}
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to send webhook notification to " + url, e);
}
return false;
}
private String url;
private String signature;
private String data;
}
}